package com.chenqq.camerademo.camera.helper;

import android.hardware.usb.UsbDevice;
import android.text.TextUtils;
import android.util.Log;

import com.chenqq.camerademo.camera.bean.USBInfo;
import com.chenqq.camerademo.camera.usb.UsbControlBlock;
import com.chenqq.camerademo.camera.usbInterface.OnDeviceConnectListener;

import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;

public class CameraUnits {

    private BehaviorSubject<USBInfo> usbInfoBehaviorSubject;
    private String Tag = getClass().getSimpleName();

    private CameraUnits() {
    }

    private static CameraUnits inStance;
    private final ConcurrentHashMap<UsbDevice, UsbControlBlock> mCtrlBlocks
            = new ConcurrentHashMap<UsbDevice, UsbControlBlock>();
    private  OnDeviceConnectListener onDeviceConnectListener;

    public static CameraUnits getInStance() {
        if (inStance == null) {
            inStance = new CameraUnits();
        }
        return inStance;
    }


    public void remove(UsbDevice usbDevice) {
        if (usbDevice != null) {
            mCtrlBlocks.remove(usbDevice);
        }
    }

    public void addCtrlBlocks(UsbDevice usbDevice, UsbControlBlock controlBlock) {
        if (usbDevice != null) {
            mCtrlBlocks.put(usbDevice, controlBlock);
        }
    }

    public void setOnDeviceConnectListener(OnDeviceConnectListener mOnDeviceConnectListener) {
//        if (this.onDeviceConnectListener!=null){
//            this.onDeviceConnectListener.onCancel(null);
//        }
        this.onDeviceConnectListener=mOnDeviceConnectListener;
    }

    /**
     * 打开USB设备
     *
     * @param info
     */
    public void openCameraUSBDevice(USBInfo info) {
        if (usbInfoBehaviorSubject == null) {
            usbInfoBehaviorSubject = BehaviorSubject.create();
            Disposable subscribe = usbInfoBehaviorSubject.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function<USBInfo, USBInfo>() {
                        @Override
                        public USBInfo apply(@NonNull USBInfo usbInfo) throws Exception {
                            UsbControlBlock ctrlBlock;
                            ctrlBlock = mCtrlBlocks.get(usbInfo.getUsbDevice());
                            if (ctrlBlock == null) {
                                ctrlBlock = new UsbControlBlock(usbInfo.getUsbDevice());
                                mCtrlBlocks.put(usbInfo.getUsbDevice(), ctrlBlock);
                                usbInfo.setCreateNew(true);
                            } else {
                                usbInfo.setCreateNew(false);
                            }
                            return usbInfo;
                        }
                    }).subscribe(new Consumer<USBInfo>() {
                        @Override
                        public void accept(USBInfo usbInfo) throws Exception {
                            int vendorId = usbInfo.getUsbDevice().getVendorId();
                            int productId = usbInfo.getUsbDevice().getProductId();
                            String tag=productId+""+vendorId;
                            if (onDeviceConnectListener != null) {
                                UsbControlBlock usbControlBlock = mCtrlBlocks.get(usbInfo.getUsbDevice());
                                onDeviceConnectListener.onConnect(tag,usbInfo.getUsbDevice(), usbControlBlock
                                        , usbInfo.isCreateNew());
                            }

                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.e(Tag, "accept: " + throwable.getMessage());
                            CameraTools.getInStance().removeDisposable(Tag);
                            usbInfoBehaviorSubject = null;
                        }
                    });
            CameraTools.getInStance().addDisposable(Tag, subscribe);
        }
        usbInfoBehaviorSubject.onNext(info);
    }


    /**
     * 关闭USB的
     * @param info
     */
    public void closeCameraUSBDevice(USBInfo info){
        UsbControlBlock usbControlBlock = mCtrlBlocks.get(info.getUsbDevice());
        if (usbControlBlock!=null){
            usbControlBlock.close();
            if (onDeviceConnectListener != null) {
                onDeviceConnectListener.onDisconnect(info.getUsbDevice(),usbControlBlock);
            }
        }
    }


}
